package com.xuecheng.content.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.base.common.TeachplanGrade;
import com.xuecheng.base.exception.CommonError;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.BindTeachplanMediaDto;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.ITeachplanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSessionException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-06-22
 */
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements ITeachplanService {

    @Autowired
    private TeachplanMapper teachplanMapper;
    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;
    @Override
    public List<TeachplanDto> findTeachplanTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    //新增或修改
    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {
        //课程计划的id
        Long id = teachplanDto.getId();
        if(id != null){
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }else{
            //取出同父同级别的课程计划数量
            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplan.setOrderby(count + 1);
            teachplanMapper.insert(teachplan);

        }
    }

    /**
     * @description 删除课程计划树型结构
     * @param teachplanId 课程id
     */
    @Transactional
    @Override
    public void deleteTeachplanById(Long teachplanId) {
        //查询课程计划
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("课程计划不存在，无法删除");
        }
        //查询课程计划是大章节还是小（1为大，2为小）
        Integer grade = teachplan.getGrade();
        //如果是大章节查询子章节
        if(Objects.equals(grade, TeachplanGrade.ONE_GRADE.getGrade())){
            //查询课程计划是否存在子节点
            LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StringUtils.isNotBlank(teachplanId.toString()),Teachplan::getParentid,teachplanId);
            List<Teachplan> teachplanList = teachplanMapper.selectList(wrapper);
            //大章节不存在子章节，可以删除
            if(teachplanList.isEmpty()){
                int i = teachplanMapper.deleteById(teachplanId);
                //删除teachplanMedia表中相关联的信息（课程计划id和课程id）
                LambdaQueryWrapper<TeachplanMedia> delWrapper = new LambdaQueryWrapper<>();
                delWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
                delWrapper.eq(TeachplanMedia::getCourseId,teachplan.getCourseId());
                teachplanMediaMapper.delete(delWrapper);
                if(i <= 0) XueChengPlusException.cast("课程计划删除失败");
            }else{
                //大章节存在子章节，抛出异常
                XueChengPlusException.cast("课程计划信息还有子级信息，无法操作");
            }
        }else{
            //否则为小章节直接删除
            int i = teachplanMapper.deleteById(teachplanId);
            if(i <= 0) XueChengPlusException.cast("课程计划删除失败");
        }
    }

    /**
     * @description 课程计划排序.
     * @param moveStatus 移动类型
     * @param teachplanId 课程id
     */
    @Transactional
    @Override
    public void teachplanMove(String moveStatus, Long teachplanId) {
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan == null){
            XueChengPlusException.cast("课程计划不存在");
        }
        if(StringUtils.isBlank(moveStatus)){
            XueChengPlusException.cast(CommonError.PARAMS_ERROR);
        }
        if(moveStatus.equals("moveup") && teachplan.getOrderby() != 1){
            teachplan.setOrderby(teachplan.getOrderby() - 1);
        }else if(moveStatus.equals("movedown") ){
            teachplan.setOrderby(teachplan.getOrderby() + 1);
        }
        //更新排序字段
        teachplanMapper.updateById(teachplan);
        List<Teachplan> teachplanChildList = teachplanMapper.selectList(new LambdaQueryWrapper<Teachplan>()
                .eq(Teachplan::getParentid, teachplanId));
        for (Teachplan teachplanChild : teachplanChildList) {
            teachplanChild.setOrderby(teachplan.getOrderby());
        }
        updateBatchById(teachplanChildList);
    }

    /**
     * @description 教学计划绑定媒资
     * @param bindTeachplanMediaDto
     * @return com.xuecheng.content.model.po.TeachplanMedia
     * @author Huangyao
     * @date 2022/9/14 22:20
     */
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
        //教学id
        Long teachplanId = bindTeachplanMediaDto.getTeachplanId();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplanId == null || teachplan == null){
            XueChengPlusException.cast("教学计划不存在");
        }
        if(teachplan.getGrade() != 2){
            XueChengPlusException.cast("只允许第二级教学计划绑定媒资文件");
        }
        if(StringUtils.isEmpty(bindTeachplanMediaDto.getMediaId())){
            XueChengPlusException.cast("绑定的媒资文件为空");
        }
        //查询教学计划媒资信息
        TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(new LambdaQueryWrapper<TeachplanMedia>()
                .eq(TeachplanMedia::getTeachplanId, teachplanId));
        if(teachplanMedia == null){
            teachplanMedia = new TeachplanMedia();
            teachplanMedia.setCourseId(teachplan.getCourseId());
            teachplanMedia.setTeachplanId(teachplanId);
            teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
            teachplanMedia.setCreateDate(LocalDateTime.now());
            teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
            teachplanMediaMapper.insert(teachplanMedia);
        }else{
            teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
            teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
            teachplanMediaMapper.updateById(teachplanMedia);
        }
        return teachplanMedia;
    }

    /**
     * @description 删除课程计划媒资信息绑定
     * @param teachPlanId 课程计划id
     * @param mediaId 媒资文件id
     */
    @Override
    public void deleteTeachplanMedia(Long teachPlanId, String mediaId) {
        if(teachPlanId == null){
            XueChengPlusException.cast("课程计划id为空");
        }
        if(StringUtils.isBlank(mediaId)){
            XueChengPlusException.cast("媒资文件id为空");
        }
        TeachplanMedia teachplanMedia = teachplanMediaMapper.selectOne(new LambdaQueryWrapper<TeachplanMedia>()
                .eq(TeachplanMedia::getTeachplanId, teachPlanId));
        if(teachplanMedia == null){
            XueChengPlusException.cast("课程计划媒资信息不存在");
        }
        try {
            teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>()
                    .eq(TeachplanMedia::getTeachplanId,teachPlanId)
                    .eq(TeachplanMedia::getMediaId,mediaId));
        } catch (SqlSessionException e) {
            XueChengPlusException.cast("删除失败");
        }
    }

    /**
     * @description 获取最新的排序号
     * @param courseId  课程id
     * @param parentId  父课程计划id
     * @return int 最新排序号
     * @author Mr.M
     * @date 2022/9/9 13:43
     */
    private int getTeachplanCount(long courseId,long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentId);
        return teachplanMapper.selectCount(queryWrapper);
    }
}
